home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / Other Langs / gawk-2.11 / awk.h < prev    next >
Text File  |  1990-09-21  |  17KB  |  646 lines

  1. /*
  2.  * awk.h -- Definitions for gawk. 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. /* use the following define because the gawk source uses NULL as int */
  27.  
  28. #ifndef NULL
  29. #define    NULL    0
  30. #endif
  31.  
  32. /* ------------------------------ Includes ------------------------------ */
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <unix.h>
  36. #include <string.h>
  37. #include <ctype.h>
  38. #include <setjmp.h>
  39.  
  40. #ifndef THINK_C
  41. #include <varargs.h>
  42. #include <types.h>
  43. #include <stat.h>
  44. #else
  45. #include <stdarg.h>
  46. #endif
  47.  
  48. #include <errno.h>
  49.  
  50. #include "regex.h"
  51.  
  52. #include "config.h"        /* local configuration */
  53.  
  54. /* ------------------- System Functions, Variables, etc ------------------- */
  55. /* nasty nasty SunOS-ism */
  56. #ifdef sparc
  57. #include <alloca.h>
  58. #ifdef lint
  59. extern char *alloca();
  60. #endif
  61. #elif !defined(THINK_C)
  62. extern char *alloca();
  63. #endif
  64.  
  65. #ifdef SPRINTF_INT
  66. extern int sprintf();
  67. #elif !defined(THINK_C)    /* not USG */
  68. /* nasty nasty berkelixm */
  69. #define setjmp    _setjmp
  70. #define longjmp    _longjmp
  71. extern char *sprintf();
  72. #endif
  73. /*
  74.  * if you don't have vprintf, but you are BSD, the version defined in
  75.  * vprintf.c should do the trick.  Otherwise, use this and cross your fingers.
  76.  */
  77. #if defined(VPRINTF_MISSING) && !defined(DOPRNT_MISSING) && !defined(BSDSTDIO)
  78. #define vfprintf(fp,fmt,arg)    _doprnt((fmt), (arg), (fp))
  79. #endif
  80.  
  81. #if defined (__STDC__) || defined(THINK_C)
  82. #ifndef THINK_C
  83. extern void *malloc(unsigned), *realloc(void *, unsigned);
  84. extern void free(char *);
  85. #endif
  86. extern char *getenv(char *);
  87.  
  88. #ifndef THINK_C
  89. extern char *strcpy(char *, char *), *strcat(char *, char *), *strncpy(char *, char *, int);
  90. extern int strcmp(char *, char *);
  91. extern int strncmp(char *, char *, int);
  92. extern int strncasecmp(char *, char *, int);
  93. extern char *strerror(int);
  94. extern char *strchr(char *, int);
  95. extern int strlen(char *);
  96. extern    char *memcpy(char *, char *, int);
  97. extern    int memcmp(char *, char *, int);
  98. extern    char *memset(char *, int, int);
  99. #endif
  100.  
  101. extern int fprintf(FILE *, char *, ...);
  102. extern int fprintf();
  103. extern int vfprintf();
  104.  
  105. #ifndef MSDOS
  106. #ifndef THINK_C
  107. extern int fwrite(char *, int, int, FILE *);
  108. #endif
  109. #endif
  110.  
  111. extern int fflush(FILE *);
  112. extern int fclose(FILE *);
  113. extern int pclose(FILE *);
  114. #ifndef MSDOS
  115. extern int fputs(char *, FILE *);
  116. #endif
  117. extern void abort();
  118. extern int isatty(int);
  119. extern void exit(int);
  120. extern int system(char *);
  121. extern int sscanf( char *, char *, ... );
  122.  
  123. extern double atof(char *);
  124. extern int fstat(int, struct stat *);
  125.  
  126. #ifndef THINK_C
  127. extern off_t lseek(int, off_t, int);
  128. extern int fseek(FILE *, long, int);
  129. extern int close(int);
  130. extern int open();
  131. extern int pipe(int *);
  132. extern int dup2(int, int);
  133. #endif
  134.  
  135. #ifndef MSDOS
  136. extern int unlink(char *);
  137. #endif
  138.  
  139. extern int fork();
  140.  
  141. #ifndef THINK_C
  142. extern int execl( char *, char *, ... );
  143. extern int read(int, char *, int);
  144. extern int wait(int *);
  145. #endif
  146.  
  147. extern void _exit(int);
  148. #else
  149. extern void _exit();
  150. extern int wait();
  151. extern int read();
  152. extern int execl();
  153. extern int fork();
  154. extern int unlink();
  155. extern int dup2();
  156. extern int pipe();
  157. extern int open();
  158. extern int close();
  159. extern int fseek();
  160. extern off_t lseek();
  161. extern int fstat();
  162. extern void exit();
  163. extern int system();
  164. extern int isatty();
  165. extern void abort();
  166. extern int fputs();
  167. extern int fclose();
  168. extern int pclose();
  169. extern int fflush();
  170. extern int fwrite();
  171. extern int fprintf();
  172. extern int vfprintf();
  173. extern int sscanf();
  174. extern char *malloc(), *realloc();
  175. extern void free();
  176. extern char *getenv();
  177.  
  178. extern int strcmp();
  179. extern int strncmp();
  180. extern int strncasecmp();
  181. extern int strlen();
  182. extern char *strcpy(), *strcat(), *strncpy();
  183. extern    char *memset();
  184. extern    int memcmp();
  185. extern    char *memcpy();
  186. extern char *strerror();
  187. extern char *strchr();
  188.  
  189. extern double atof();
  190. #endif
  191.  
  192. #ifndef MSDOS
  193. extern int errno;
  194. #endif    /* MSDOS */
  195.  
  196. /* ------------------ Constants, Structures, Typedefs  ------------------ */
  197. #define AWKNUM    double
  198.  
  199. typedef enum {
  200.     /* illegal entry == 0 */
  201.     Node_illegal,
  202.  
  203.     /* binary operators  lnode and rnode are the expressions to work on */
  204.     Node_times,
  205.     Node_quotient,
  206.     Node_mod,
  207.     Node_plus,
  208.     Node_minus,
  209.     Node_cond_pair,        /* conditional pair (see Node_line_range) */
  210.     Node_subscript,
  211.     Node_concat,
  212.     Node_exp,
  213.  
  214.     /* unary operators   subnode is the expression to work on */
  215. /*10*/    Node_preincrement,
  216.     Node_predecrement,
  217.     Node_postincrement,
  218.     Node_postdecrement,
  219.     Node_unary_minus,
  220.     Node_field_spec,
  221.  
  222.     /* assignments   lnode is the var to assign to, rnode is the exp */
  223.     Node_assign,
  224.     Node_assign_times,
  225.     Node_assign_quotient,
  226.     Node_assign_mod,
  227. /*20*/    Node_assign_plus,
  228.     Node_assign_minus,
  229.     Node_assign_exp,
  230.  
  231.     /* boolean binaries   lnode and rnode are expressions */
  232.     Node_and,
  233.     Node_or,
  234.  
  235.     /* binary relationals   compares lnode and rnode */
  236.     Node_equal,
  237.     Node_notequal,
  238.     Node_less,
  239.     Node_greater,
  240.     Node_leq,
  241. /*30*/    Node_geq,
  242.     Node_match,
  243.     Node_nomatch,
  244.  
  245.     /* unary relationals   works on subnode */
  246.     Node_not,
  247.  
  248.     /* program structures */
  249.     Node_rule_list,        /* lnode is a rule, rnode is rest of list */
  250.     Node_rule_node,        /* lnode is pattern, rnode is statement */
  251.     Node_statement_list,    /* lnode is statement, rnode is more list */
  252.     Node_if_branches,    /* lnode is to run on true, rnode on false */
  253.     Node_expression_list,    /* lnode is an exp, rnode is more list */
  254.     Node_param_list,    /* lnode is a variable, rnode is more list */
  255.  
  256.     /* keywords */
  257. /*40*/    Node_K_if,        /* lnode is conditonal, rnode is if_branches */
  258.     Node_K_while,        /* lnode is condtional, rnode is stuff to run */
  259.     Node_K_for,        /* lnode is for_struct, rnode is stuff to run */
  260.     Node_K_arrayfor,    /* lnode is for_struct, rnode is stuff to run */
  261.     Node_K_break,        /* no subs */
  262.     Node_K_continue,    /* no stuff */
  263.     Node_K_print,        /* lnode is exp_list, rnode is redirect */
  264.     Node_K_printf,        /* lnode is exp_list, rnode is redirect */
  265.     Node_K_next,        /* no subs */
  266.     Node_K_exit,        /* subnode is return value, or NULL */
  267.     Node_K_do,        /* lnode is conditional, rnode stuff to run */
  268.     Node_K_return,
  269.     Node_K_delete,
  270.     Node_K_getline,
  271.     Node_K_function,    /* lnode is statement list, rnode is params */
  272.  
  273.     /* I/O redirection for print statements */
  274.     Node_redirect_output,    /* subnode is where to redirect */
  275.     Node_redirect_append,    /* subnode is where to redirect */
  276.     Node_redirect_pipe,    /* subnode is where to redirect */
  277.     Node_redirect_pipein,    /* subnode is where to redirect */
  278.     Node_redirect_input,    /* subnode is where to redirect */
  279.  
  280.     /* Variables */
  281.     Node_var,        /* rnode is value, lnode is array stuff */
  282.     Node_var_array,        /* array is ptr to elements, asize num of
  283.                  * eles */
  284.     Node_val,        /* node is a value - type in flags */
  285.  
  286.     /* Builtins   subnode is explist to work on, proc is func to call */
  287.     Node_builtin,
  288.  
  289.     /*
  290.      * pattern: conditional ',' conditional ;  lnode of Node_line_range
  291.      * is the two conditionals (Node_cond_pair), other word (rnode place)
  292.      * is a flag indicating whether or not this range has been entered.
  293.      */
  294.     Node_line_range,
  295.  
  296.     /*
  297.      * boolean test of membership in array lnode is string-valued
  298.      * expression rnode is array name 
  299.      */
  300.     Node_in_array,
  301.  
  302.     Node_func,        /* lnode is param. list, rnode is body */
  303.     Node_func_call,        /* lnode is name, rnode is argument list */
  304.  
  305.     Node_cond_exp,        /* lnode is conditonal, rnode is if_branches */
  306.     Node_regex,
  307.     Node_hashnode,
  308.     Node_ahash
  309. } NODETYPE;
  310.  
  311. /*
  312.  * NOTE - this struct is a rather kludgey -- it is packed to minimize
  313.  * space usage, at the expense of cleanliness.  Alter at own risk.
  314.  */
  315. typedef struct exp_node {
  316.     union {
  317.         struct {
  318.             union {
  319.                 struct exp_node *lptr;
  320.                 char *param_name;
  321.                 char *retext;
  322.                 struct exp_node *nextnode;
  323.             } l;
  324.             union {
  325.                 struct exp_node *rptr;
  326.                 struct exp_node *(*pptr) ();
  327.                 struct re_pattern_buffer *preg;
  328.                 struct for_loop_header *hd;
  329.                 struct exp_node **av;
  330.                 int r_ent;    /* range entered */
  331.             } r;
  332.             char *name;
  333.             short number;
  334.             unsigned char recase;
  335.         } nodep;
  336.         struct {
  337.             AWKNUM fltnum;    /* this is here for optimal packing of
  338.                      * the structure on many machines
  339.                      */
  340.             char *sp;
  341.             short slen;
  342.             unsigned char sref;
  343.         } val;
  344.         struct {
  345.             struct exp_node *next;
  346.             char *name;
  347.             int length;
  348.             struct exp_node *value;
  349.         } hash;
  350. #define    hnext    sub.hash.next
  351. #define    hname    sub.hash.name
  352. #define    hlength    sub.hash.length
  353. #define    hvalue    sub.hash.value
  354.         struct {
  355.             struct exp_node *next;
  356.             struct exp_node *name;
  357.             struct exp_node *value;
  358.         } ahash;
  359. #define    ahnext    sub.ahash.next
  360. #define    ahname    sub.ahash.name
  361. #define    ahvalue    sub.ahash.value
  362.     } sub;
  363.     NODETYPE type;
  364.     unsigned char flags;
  365. #            define    MEM    0x7
  366. #            define    MALLOC    1    /* can be free'd */
  367. #            define    TEMP    2    /* should be free'd */
  368. #            define    PERM    4    /* can't be free'd */
  369. #            define    VAL    0x18
  370. #            define    NUM    8    /* numeric value is valid */
  371. #            define    STR    16    /* string value is valid */
  372. #            define    NUMERIC    32    /* entire field is numeric */
  373. } NODE;
  374.  
  375. #define lnode    sub.nodep.l.lptr
  376. #define nextp    sub.nodep.l.nextnode
  377. #define rnode    sub.nodep.r.rptr
  378. #define source_file    sub.nodep.name
  379. #define    source_line    sub.nodep.number
  380. #define    param_cnt    sub.nodep.number
  381. #define param    sub.nodep.l.param_name
  382.  
  383. #define subnode    lnode
  384. #define proc    sub.nodep.r.pptr
  385.  
  386. #define reexp    lnode
  387. #define rereg    sub.nodep.r.preg
  388. #define re_case sub.nodep.recase
  389. #define re_text sub.nodep.l.retext
  390.  
  391. #define forsub    lnode
  392. #define forloop    rnode->sub.nodep.r.hd
  393.  
  394. #define stptr    sub.val.sp
  395. #define stlen    sub.val.slen
  396. #define stref    sub.val.sref
  397. #define    valstat    flags
  398.  
  399. #define numbr    sub.val.fltnum
  400.  
  401. #define var_value lnode
  402. #define var_array sub.nodep.r.av
  403.  
  404. #define condpair lnode
  405. #define triggered sub.nodep.r.r_ent
  406.  
  407. #define HASHSIZE 101
  408.  
  409. typedef struct for_loop_header {
  410.     NODE *init;
  411.     NODE *cond;
  412.     NODE *incr;
  413. } FOR_LOOP_HEADER;
  414.  
  415. /* for "for(iggy in foo) {" */
  416. struct search {
  417.     int numleft;
  418.     NODE **arr_ptr;
  419.     NODE *bucket;
  420.     NODE *retval;
  421. };
  422.  
  423. /* for faster input, bypass stdio */
  424. typedef struct iobuf {
  425.     int fd;
  426.     char *buf;
  427.     char *off;
  428.     int size;    /* this will be determined by an fstat() call */
  429.     int cnt;
  430.     char *secbuf;
  431.     int secsiz;
  432.     int flag;
  433. #    define        IOP_IS_TTY    1
  434. } IOBUF;
  435.  
  436. /*
  437.  * structure used to dynamically maintain a linked-list of open files/pipes
  438.  */
  439. struct redirect {
  440.     int flag;
  441. #        define        RED_FILE    1
  442. #        define        RED_PIPE    2
  443. #        define        RED_READ    4
  444. #        define        RED_WRITE    8
  445. #        define        RED_APPEND    16
  446. #        define        RED_NOBUF    32
  447.     char *value;
  448.     FILE *fp;
  449.     IOBUF *iop;
  450.     int pid;
  451.     int status;
  452.     long offset;        /* used for dynamic management of open files */
  453.     struct redirect *prev;
  454.     struct redirect *next;
  455. };
  456.  
  457. /* longjmp return codes, must be nonzero */
  458. /* Continue means either for loop/while continue, or next input record */
  459. #define TAG_CONTINUE 1
  460. /* Break means either for/while break, or stop reading input */
  461. #define TAG_BREAK 2
  462. /* Return means return from a function call; leave value in ret_node */
  463. #define    TAG_RETURN 3
  464.  
  465. #ifdef MSDOS
  466. #define HUGE    0x7fff
  467. #else
  468. #define HUGE    0x7fffffff
  469. #endif
  470.  
  471. /* -------------------------- External variables -------------------------- */
  472. /* gawk builtin variables */
  473. extern NODE *FS_node, *NF_node, *RS_node, *NR_node;
  474. extern NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
  475. extern NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
  476. extern NODE *IGNORECASE_node;
  477.  
  478. extern NODE **stack_ptr;
  479. extern NODE *Nnull_string;
  480. extern NODE *deref;
  481. extern NODE **fields_arr;
  482. extern int sourceline;
  483. extern char *source;
  484. extern NODE *expression_value;
  485.  
  486. extern NODE *variables[];
  487.  
  488. extern NODE *_t;    /* used as temporary in tree_eval */
  489.  
  490. extern char *myname;
  491.  
  492. extern int node0_valid;
  493. extern int field_num;
  494. extern int strict;
  495.  
  496. /* ------------------------- Pseudo-functions ------------------------- */
  497. #define is_identchar(c) (isalnum(c) || (c) == '_')
  498.  
  499.  
  500. #define    free_temp(n)    if ((n)->flags&TEMP) { deref = (n); do_deref(); } else
  501. #define    tree_eval(t)    (_t = (t),(_t) == NULL ? Nnull_string : \
  502.             ((_t)->type == Node_val ? (_t) : r_tree_eval((_t))))
  503. #define    make_string(s,l)    make_str_node((s),(l),0)
  504.  
  505. #define    cant_happen()    fatal("line %d, file: %s; bailing out", \
  506.                 __LINE__, __FILE__);
  507. #ifdef MEMDEBUG
  508. #define memmsg(x,y,z,zz)    fprintf(stderr, "malloc: %s: %s: %d %0x\n", z, x, y, zz)
  509. #define free(s)    fprintf(stderr, "free: s: %0x\n", s), do_free(s)
  510. #else
  511. #define memmsg(x,y,z,zz)
  512. #endif
  513.  
  514. #define    emalloc(var,ty,x,str)    if ((var = (ty) malloc((unsigned)(x))) == NULL)\
  515.                     fatal("%s: %s: can't allocate memory (%s)",\
  516.                     (str), "var", strerror(errno)); else\
  517.                     memmsg("var", x, str, var)
  518. #define    erealloc(var,ty,x,str)    if((var=(ty)realloc((char *)var,\
  519.                         (unsigned)(x)))==NULL)\
  520.                     fatal("%s: %s: can't allocate memory (%s)",\
  521.                     (str), "var", strerror(errno)); else\
  522.                     memmsg("re: var", x, str, var)
  523. #ifdef DEBUG
  524. #define    force_number    r_force_number
  525. #define    force_string    r_force_string
  526. #else
  527. #ifdef lint
  528. extern AWKNUM force_number();
  529. #endif
  530. #ifdef MSDOS
  531. extern double _msc51bug;
  532. #define    force_number(n)    (_msc51bug=(_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t)))
  533. #else
  534. #define    force_number(n)    (_t = (n),(_t->flags & NUM) ? _t->numbr : r_force_number(_t))
  535. #endif
  536. #define    force_string(s)    (_t = (s),(_t->flags & STR) ? _t : r_force_string(_t))
  537. #endif
  538.  
  539. #define    STREQ(a,b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  540. #define    STREQN(a,b,n)    ((n) && *(a) == *(b) && strncmp((a), (b), (n)) == 0)
  541.  
  542. #define    WHOLELINE    (node0_valid ? fields_arr[0] : *get_field(0,0))
  543.  
  544. /* ------------- Function prototypes or defs (as appropriate) ------------- */
  545. #if defined(__STDC__) || defined (THINK_C)
  546. extern    int parse_escape(char **);
  547. extern    int devopen(char *, char *);
  548. extern    struct re_pattern_buffer *make_regexp(NODE *, int);
  549. extern    struct re_pattern_buffer *mk_re_parse(char *, int);
  550. extern    NODE *variable(char *);
  551. extern    NODE *install(NODE **, char *, NODE *);
  552. extern    NODE *lookup(NODE **, char *);
  553. extern    NODE *make_name(char *, NODETYPE);
  554. extern    int interpret(NODE *);
  555. extern    NODE *r_tree_eval(NODE *);
  556. extern    void assign_number(NODE **, double);
  557. extern    int cmp_nodes(NODE *, NODE *);
  558. extern    struct redirect *redirect(NODE *, int *);
  559. extern    int flush_io(void);
  560. extern    void print_simple(NODE *, FILE *);
  561. extern    void warning(char *,...); 
  562. extern    void fatal(char *,...); 
  563.  
  564. extern    void set_record(char *, int);
  565. extern    NODE **get_field(int, int);
  566. extern    NODE **get_lhs(NODE *, int);
  567. extern    void do_deref(void );
  568. extern    struct search *assoc_scan(NODE *);
  569. extern    struct search *assoc_next(struct search *);
  570. extern    NODE **assoc_lookup(NODE *, NODE *);
  571. extern    double r_force_number(NODE *);
  572. extern    NODE *r_force_string(NODE *);
  573. extern    NODE *newnode(NODETYPE);
  574. extern    NODE *dupnode(NODE *);
  575. extern    NODE *make_number(double);
  576. extern    NODE *tmp_number(double);
  577. extern    NODE *make_str_node(char *, int, int);
  578. extern    NODE *tmp_string(char *, int);
  579. extern    char *re_compile_pattern(char *, int, struct re_pattern_buffer *);
  580. extern    int re_search(struct re_pattern_buffer *, char *, int, int, int, struct re_registers *);
  581. extern    void freenode(NODE *);
  582.  
  583. #else
  584. extern    int parse_escape();
  585. extern    void freenode();
  586. extern    int devopen();
  587. extern    struct re_pattern_buffer *make_regexp();
  588. extern    struct re_pattern_buffer *mk_re_parse();
  589. extern    NODE *variable();
  590. extern    NODE *install();
  591. extern    NODE *lookup();
  592. extern    int interpret();
  593. extern    NODE *r_tree_eval();
  594. extern    void assign_number();
  595. extern    int cmp_nodes();
  596. extern    struct redirect *redirect();
  597. extern    int flush_io();
  598. extern    void print_simple();
  599. extern    void warning();
  600. extern    void fatal();
  601. extern    void set_record();
  602. extern    NODE **get_field();
  603. extern    NODE **get_lhs();
  604. extern    void do_deref();
  605. extern    struct search *assoc_scan();
  606. extern    struct search *assoc_next();
  607. extern    NODE **assoc_lookup();
  608. extern    double r_force_number();
  609. extern    NODE *r_force_string();
  610. extern    NODE *newnode();
  611. extern    NODE *dupnode();
  612. extern    NODE *make_number();
  613. extern    NODE *tmp_number();
  614. extern    NODE *make_str_node();
  615. extern    NODE *tmp_string();
  616. extern    char *re_compile_pattern();
  617. extern    int re_search();
  618. #endif
  619.  
  620. #if !defined(__STDC__) && !defined(THINK_C) || __STDC__ <= 0
  621. #define volatile
  622. #endif
  623.  
  624. /* Figure out what '\a' really is. */
  625. #if defined(__STDC__) || defined(THINK_C)
  626. #define BELL    '\a'        /* sure makes life easy, don't it? */
  627. #else
  628. #    if 'z' - 'a' == 25    /* ascii */
  629. #        if 'a' != 97    /* machine is dumb enough to use mark parity */
  630. #            define BELL    '\207'
  631. #        else
  632. #            define BELL    '\07'
  633. #        endif
  634. #    else
  635. #        define BELL    '\057'
  636. #    endif
  637. #endif
  638.  
  639. #ifndef SIGTYPE
  640. #define SIGTYPE    void
  641. #endif
  642.  
  643. extern char casetable[];    /* for case-independent regexp matching */
  644.  
  645. #include "Prototypes.h"
  646.